stack too deep回避チートシート
Stack too deepにギリギリならない実例をずらっと並べます。stackレベルで確認したい方はhttps://ethervm.io/ をみながらremixのデバッガーを起動して確認してみてください。また、全てのパターンを洗い出すことは不可能なので必要に応じて以下のパターンから類似のものをコピペしてご自分でガシガシいじってみてください。stack too deep問題についてはstack too deep を攻略するをご参照ください。 目次
〜 function/event/Struct 単体系 〜
1. functionの引数
2. functionの引数を参照
3. eventの引数
4. structのプロパティ
5. 二階建のstructのプロパティ
6. 三階建のstructの三階のプロパティ
〜 Struct × function/array 系 〜
7. Structをinternalな配列に格納し、参照する時のstructのプロパティの限界
8. Structをpublicな配列に格納し、参照する時のstructのプロパティの限界
9. Structを関数の引数として格納する時のstructのプロパティの限界
10. Structをeventに格納する時のstructのプロパティの限界
11. Structを関数の引数に格納する時の関数の引数の限界
12. Structをeventに格納する時の関数の引数の限界
〜 Struct × array /event 系〜
13. Structをinternalな配列から参照し、eventではく時のstructの限界
14. 二階建てのStructをinternalな配列から参照し、eventではく時のstructのプロパティの限界
〜 array × function 系〜
15. functionの引数のarrayが持てる要素
1. functionの引数の数の限界
限界:16
code: STD_Function(Javascript)
pragma solidity ^0.5.0;
contract STD_Function {
function FireEvent(
uint a1, uint a2, uint a3, uint a4, uint a5, uint a6,
uint a7, uint a8, uint a9, uint a10, uint a11, uint a12,
uint a13, uint a14, uint a15, uint a16 //uint a17を追加しようとすると stack too deep
) public {
}
}
2. functionの引数を参照する時の限界
限界: a2~a16は参照できるけど17番目のスロットにあるa1は参照できない
code: STD_Function(Javascript)
pragma solidity ^0.5.0;
contract STD_Function {
event Fire(uint arg1, uint arg2);
function FireEvent(
uint a1, uint a2, uint a3, uint a4, uint a5, uint a6,
uint a7, uint a8, uint a9, uint a10, uint a11, uint a12,
uint a13, uint a14, uint a15, uint a16
) public {
emit Fire(a2,a16);
//emit Fire(a1,a16); a1をemitしようとすると stack too deep
}
}
3. Eventの引数の数の限界
限界:14
code: STD_Event(Javascript)
pragma solidity ^0.5.0;
contract STD_Event {
event Fire(
uint a1, uint a2, uint a3, uint a4, uint a5, uint a6,
uint a7, uint a8, uint a9, uint a10, uint a11, uint a12,
uint a13, uint a14 //uint a15を追加しようとすると stack too deep
);
function FireEvent(uint a1, uint a2, uint a3) public {
emit Fire(a1,a2,a3,a1,a2,a3,a1,a2,a3,a1,a2,a3,a1,a2);
}
}
4. Structのプロパティ数の限界
限界: なし(20はいけた)
code: STD_Function(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_Struct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
uint a10;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
string a20;
}
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,num,
_str,_str,_str,_str,_str,_str,_str,_str,_str,_str
);
}
}
5. structを二階までネストさせた時のstructのプロパティ数の限界
限界:なし(一階も二階も20はいけた)
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_NestedStruct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
uint a10;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
string a20;
}
struct MetaStruct {
BigStruct struct1;
BigStruct struct2;
BigStruct struct3;
BigStruct struct4;
BigStruct struct5;
BigStruct struct6;
BigStruct struct7;
BigStruct struct8;
BigStruct struct9;
BigStruct struct10;
BigStruct struct11;
BigStruct struct12;
BigStruct struct13;
BigStruct struct14;
BigStruct struct15;
BigStruct struct16;
BigStruct struct17;
BigStruct struct18;
BigStruct struct19;
BigStruct struct20;
}
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,num
,_str,_str, _str,_str, _str,_str, _str,_str, _str,_str
);
MetaStruct(
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct
);
}
}
7. structを三階までネストさせた時のstructのプロパティ数の限界
限界:なし(一階も二階も三階も20はいけた)←コントラクトサイズはオーバー
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_NestedStruct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
uint a10;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
string a20;
}
struct MetaStruct {
BigStruct struct1;
BigStruct struct2;
BigStruct struct3;
BigStruct struct4;
BigStruct struct5;
BigStruct struct6;
BigStruct struct7;
BigStruct struct8;
BigStruct struct9;
BigStruct struct10;
BigStruct struct11;
BigStruct struct12;
BigStruct struct13;
BigStruct struct14;
BigStruct struct15;
BigStruct struct16;
BigStruct struct17;
BigStruct struct18;
BigStruct struct19;
BigStruct struct20;
}
struct MetaMetaStruct {
MetaStruct struct1;
MetaStruct struct2;
MetaStruct struct3;
MetaStruct struct4;
MetaStruct struct5;
MetaStruct struct6;
MetaStruct struct7;
MetaStruct struct8;
MetaStruct struct9;
MetaStruct struct10;
MetaStruct struct11;
MetaStruct struct12;
MetaStruct struct13;
MetaStruct struct14;
MetaStruct struct15;
MetaStruct struct16;
MetaStruct struct17;
MetaStruct struct18;
MetaStruct struct19;
MetaStruct struct20;
}
MetaMetaStruct[] Array;
event Fire(MetaMetaStruct a1);
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,num
,_str,_str, _str,_str, _str,_str, _str,_str, _str,_str
);
MetaStruct memory NewMetaStruct = MetaStruct(
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct
);
Array.push(MetaMetaStruct(
NewMetaStruct,NewMetaStruct,NewMetaStruct,NewMetaStruct,NewMetaStruct,
NewMetaStruct,NewMetaStruct,NewMetaStruct,NewMetaStruct,NewMetaStruct,
NewMetaStruct,NewMetaStruct,NewMetaStruct,NewMetaStruct,NewMetaStruct,
NewMetaStruct,NewMetaStruct,NewMetaStruct,NewMetaStruct,NewMetaStruct
));
GetStruct();
}
function GetStruct()private{
emit Fire(Array0); //ついでにイベントでもはいてみた }
}
8. Structをinternalな配列に格納し、参照する時のstructのプロパティ数の限界
限界: なし(20はいけた)
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_Struct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
uint a10;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
string a20;
}
BigStruct[] Array;
event Fire(BigStruct a1);
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,num,
_str,_str,_str,_str,_str,_str,_str,_str,_str,_str
);
Array.push(NewStruct);
GetStruct();
}
function GetStruct()private{
BigStruct memory Get = Array0; }
}
9. Structをpublicな配列に格納し、参照する時のstructのプロパティ数の限界
限界: 12
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_Struct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
uint a10;
string a11;
string a12;
//string a13; を追加しようとすると stack too deep
}
BigStruct[] public Array;
event Fire(BigStruct a1);
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,num,_str,_str
);
Array.push(NewStruct);
GetStruct();
}
function GetStruct()private{
BigStruct memory Get = Array0; }
}
10. Structを関数の引数として格納する時のstructのプロパティ数の限界
限界: なし(20はいけた)
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_Struct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
uint a10;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
string a20;
}
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,num,_str,_str,_str,
_str,_str,_str,_str,_str,_str,_str
);
GetStruct(NewStruct);
}
function GetStruct(BigStruct _NewStruct)private returns(BigStruct){
return _NewStruct;
}
}
11. Structをeventに格納する時のstructのプロパティ数の限界
限界: なし(27はいけた)
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_Struct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
uint a21;
uint a22;
uint a23;
uint a24;
uint a25;
uint a26;
uint a27;
uint a28;
uint a29;
}
event Fire(BigStruct a1);
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,_str,_str,_str,_str,_str,_str,
_str,_str,_str,num,num,num,num,num,num,num,num,num
);
emit Fire(NewStruct);
}
}
12. Structを関数の引数に格納する時の関数の引数の数の限界
限界: 16
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_Struct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
uint a10;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
string a20;
}
BigStruct[] Array;
event Fire(BigStruct a1);
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,num,_str,_str,_str,_str,_str,_str,_str,_str,_str,_str
);
GetStruct(
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct
);
}
function GetStruct(
BigStruct memory _NewStruct1,BigStruct memory _NewStruct2,BigStruct memory _NewStruct3,
BigStruct memory _NewStruct4,BigStruct memory _NewStruct5,BigStruct memory _NewStruct6,
BigStruct memory _NewStruct7,BigStruct memory _NewStruc8,BigStruct memory _NewStruct9,
BigStruct memory _NewStruct10,BigStruct memory _NewStruct11,BigStruct memory _NewStruct12,
BigStruct memory _NewStruct13,BigStruct memory _NewStruc14,BigStruct memory _NewStruct15
//BigStruct memory _NewStruct16 を追加しようとすると stack too deep
)private{
}
}
13. structをeventに格納する時の関数の引数の数の限界
限界: 12
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_Struct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
uint a21;
uint a22;
uint a23;
uint a24;
uint a25;
uint a26;
uint a27;
uint a28;
uint a29;
}
event Fire(
BigStruct a1,BigStruct a2,BigStruct a3,BigStruct a4,BigStruct a5,BigStruct a6,BigStruct a7,
BigStruct a8,BigStruct a9,BigStruct a10,BigStruct a11,BigStruct a12
//BigStruct a13 を追加しようとすると stack too deep
);
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,_str,_str,_str,_str,_str,_str,_str,
_str,_str,num,num,num,num,num,num,num,num,num
);
emit Fire(
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct
);
}
}
14. Structをinternalな配列から参照し、eventではく時のstructのプロパティ数の限界
限界: なし(20はいけた)
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_Struct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
uint a10;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
string a20;
}
BigStruct[] Array;
event Fire(BigStruct a1);
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,num
,_str,_str, _str,_str, _str,_str, _str,_str, _str,_str
);
Array.push(NewStruct);
GetStruct();
}
function GetStruct()private{
}
}
15. 二階建てのStructをinternalな配列から参照し、eventではく時のstructのプロパティ数の限界
限界: なし(一階も二階も20はいけた)
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
contract STD_NestedStruct {
struct BigStruct {
uint a1;
uint a2;
uint a3;
uint a4;
uint a5;
uint a6;
uint a7;
uint a8;
uint a9;
uint a10;
string a11;
string a12;
string a13;
string a14;
string a15;
string a16;
string a17;
string a18;
string a19;
string a20;
}
struct MetaStruct {
BigStruct struct1;
BigStruct struct2;
BigStruct struct3;
BigStruct struct4;
BigStruct struct5;
BigStruct struct6;
BigStruct struct7;
BigStruct struct8;
BigStruct struct9;
BigStruct struct10;
BigStruct struct11;
BigStruct struct12;
BigStruct struct13;
BigStruct struct14;
BigStruct struct15;
BigStruct struct16;
BigStruct struct17;
BigStruct struct18;
BigStruct struct19;
BigStruct struct20;
}
MetaStruct[] Array;
event Fire(MetaStruct a1);
function CreateStruct(uint num, string memory _str)public{
BigStruct memory NewStruct = BigStruct(
num,num,num,num,num,num,num,num,num,num
,_str,_str, _str,_str, _str,_str, _str,_str, _str,_str
);
MetaStruct(
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,
NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct,NewStruct
);
GetStruct();
}
function GetStruct()private{
}
}
15. functionの引数がarrayの時の引数の数
限界: 16 (arrayだろうがなんだろうが関係ない)
code: STD_Struct(Javascript)
pragma solidity ^0.5.0;
contract STD_Event {
function FireEvent(
uint[] memory array1,uint[] memory array2,
uint[] memory array3,uint[] memory array4,
uint[] memory array5,uint[] memory array6,
uint[] memory array7,uint[] memory array8,
uint[] memory array9,uint[] memory array10,
uint[] memory array11,uint[] memory array12,
uint[] memory array13,uint[] memory array14,
uint[] memory array15,uint[] memory array16
) public {
}
}
必要に応じて随時更新しますので、上記ないパターンがありましたら↓に書いておいてください。